﻿using GenericStateMachine;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace GenericStateMachine.Test
{
    [TestClass]
    public class ExpressionHelperTest
    {

        [TestMethod]
        public void GetMemberNameTest()
        {
            Expression<Action<TestApi>> func = x => x.Action0();
            Expression<Func<TestApi, int>> prop = x => x.Prop;
            Expression<Func<TestApi, int>> e = null;

            ExpressionHelper.GetMemberName(func).Is("Action0");
            ExpressionHelper.GetMemberName(prop).Is("Prop");

            AssertEx.Throws<ArgumentNullException>(() => ExpressionHelper.GetMemberName(e));
        }

        private void ValueIncludedTest(byte param)
        {
            Expression<Action<TestApi>> action0 = s => s.Action0();

            Expression<Action<TestApi, byte>> action1a = (s, p) => s.Action1(p);
            Expression<Action<TestApi>> action1b = s => s.Action1(0);
            Expression<Action<TestApi>> action1c = s => s.Action1(param);

            Expression<Action<TestApi, byte, short, int, long>> action4a = (s, p1, p2, p3, p4) => s.Action4(p1, p2, p3, p4);
            Expression<Action<TestApi, byte, short, int>> action4b = (s, p1, p2, p3) => s.Action4(p1, p2, p3, 0);
            Expression<Action<TestApi, short, int, long>> action4c = (s, p1, p2, p3) => s.Action4(param, p1, p2, p3);

            Expression<Func<TestApi, int>> prop = s => s.Prop;

            Expression<Func<TestApi, int>> nullex = null;
            Expression<Func<int, int, int>> plus = (x, y) => x + y;

            ExpressionHelper.ValueIncluded(action0).IsFalse();

            ExpressionHelper.ValueIncluded(action1a).IsFalse();
            ExpressionHelper.ValueIncluded(action1b).IsTrue();
            ExpressionHelper.ValueIncluded(action1c).IsTrue();

            ExpressionHelper.ValueIncluded(action4a).IsFalse();
            ExpressionHelper.ValueIncluded(action4b).IsTrue();
            ExpressionHelper.ValueIncluded(action4c).IsTrue();

            ExpressionHelper.ValueIncluded(prop).IsFalse();

            AssertEx.Throws<ArgumentNullException>(() =>
            {
                ExpressionHelper.ValueIncluded(nullex);
            });

            AssertEx.Throws<ArgumentException>(() =>
            {
                ExpressionHelper.ValueIncluded(plus);
            });
        }

        [TestMethod]
        public void ValueIncludedTest()
        {
            ValueIncludedTest(0);
        }
    }
}
